#include <iostream>
#include "Sock.hpp"
#include "Protocol.hpp"
#include <pthread.h>
#include <unistd.h>
#include <string.h>
using namespace std;

// 5.提供服务
void *handle(void *args)
{
    int newfd = *(int *)args;
    delete (int *)args;
    // 获取请求,对接受到的request请求进行反序列化
    char buffer[1024];
    request_t req;
    memset(&req, 0, sizeof(req));
    size_t s = read(newfd, buffer, sizeof(buffer) - 1);
    if (s > 0)
    {
        buffer[s]=0;
        string jsonstring = buffer;
        DeserializeRequest(jsonstring, req);
        // 处理请求
        response_t res = {0, 0};
        switch (req.op)
        {
        case '+':
            res.result = req.x + req.y;
            break;
        case '-':
            res.result = req.x - req.y;
            break;
        case '*':
            res.result = req.x * req.y;
            break;
        case '/':
            if (req.y == 0)
            {
                res.code = 1;
                cout << "除零错误" << endl;
                break;
            } // 除零错误
            res.result = req.x / req.y;
            break;
        case '%':
            if (req.y == 0)
            {
                res.code = 2;
                cout << "除零错误" << endl;
                break;
            }
            // 除零错误
            res.result = req.x % req.y;

            break;
        default:
            res.code = 3; // 操作符非法
            cout << "请输入合法的操作符 " << endl;
            break;
        }
        cout << "request: " << req.x << req.op << req.y << endl;
        // 做出回应
        // 对回应进行序列化
        string json_string1 = SerializeResponse(res);
        write(newfd, json_string1.c_str(), json_string1.size());
    }

    close(newfd);
}

int main(int args, char *argv[])
{
    // 1.创建套接字文件
    int listenfd = Socket::Sock();
    // 2.绑定IP和端口号
    Socket::Bind(listenfd, atoi(argv[1]));
    // 3.进行监听
    Socket::Listen(listenfd);
    for (;;)
    {
        // 4.获取连接
        int fd = Socket::Accept(listenfd);
        int *newfd = new int(fd);
        pthread_t tid;
        pthread_create(&tid, nullptr, handle, (void *)newfd);
    }

    return 0;
}